package com.example.controller;

import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.dao.authMapper.UserMapper;
import com.example.pojo.LoginUser;
import com.example.pojo.ResponseVo;
import com.example.util.Sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;


@RestController
@CrossOrigin
public class Demo1Controller {


    @Autowired
    private TokenEndpoint tokenEndpoint;
    @Autowired
    private UserMapper userMapper;

    @RequestMapping("/sdsd/sdsd")
    public void dsd() {
        System.out.println("sdfsdfsdf");
    }

    @PostMapping("/oauth/login")
    public ResponseVo login(@RequestBody LoginUser user) throws HttpRequestMethodNotSupportedException {
        LambdaQueryWrapper<LoginUser> eq = new QueryWrapper<LoginUser>().lambda().eq(LoginUser::getLoginCode, user.getUsername());
        LoginUser loginUser = userMapper.selectOne(eq);
        if (loginUser == null)
            return ResponseVo.no("未查询到该用户");
        if (!user.getPassword().equals(loginUser.getPassword()))
            return ResponseVo.no("密码错误");
        if (new Date().getTime() > loginUser.getExpireTime().getTime())
            return ResponseVo.no("账号已过期");
// 清楚已存在token 重制token时长
        deletToken(loginUser.getLoginCode());
        UsernamePasswordAuthenticationToken client = new UsernamePasswordAuthenticationToken("client", null, new ArrayList<>());
        HashMap<String, String> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("grant_type", "password");
        objectObjectHashMap.put("client_id", "client");
        objectObjectHashMap.put("client_secret", "123456");
        objectObjectHashMap.put("username", loginUser.getLoginCode());
        objectObjectHashMap.put("password", loginUser.getPassword());
        ResponseEntity<OAuth2AccessToken> oAuth2AccessTokenResponseEntity = tokenEndpoint.postAccessToken(client, objectObjectHashMap);
        return ResponseVo.success(oAuth2AccessTokenResponseEntity.getBody());
    }


    public void deletToken(String username){
        userMapper.deleteReshToken(username);
        userMapper.deleteToken(username);
    }

    @GetMapping("/oauth/captcha")
    public ResponseEntity<byte[]> generateCaptcha() throws IOException {
        int width = 200;
        int height = 100;
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = bufferedImage.createGraphics();

        // Set background color
        Color backgroundColor = new Color(255, 255, 255); // White background
        g2d.setColor(backgroundColor);
        g2d.fillRect(0, 0, width, height);

        // Draw random interference lines
        drawInterferenceLines(g2d, width, height);

        // Generate random captcha text
        String captchaText = generateRandomText(6);

        // Set font and color for the captcha text
        g2d.setFont(new Font("Arial", Font.BOLD, 40));
        Color textColor = new Color(98, 218, 88, 250); // Black text
        g2d.setColor(textColor);

        // Draw the captcha text with some distortion
        drawDistortedText(g2d, captchaText);

        // Clean up
        g2d.dispose();

        // Convert BufferedImage to byte array
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "png", baos);
        byte[] imageBytes = baos.toByteArray();

        // Set headers and return the image
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_PNG);
        return ResponseEntity.ok().headers(headers).body(imageBytes);
    }

    private void drawInterferenceLines(Graphics2D g2d, int width, int height) {
        g2d.setColor(Color.LIGHT_GRAY);
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int x2 = random.nextInt(width);
            int y2 = random.nextInt(height);
            g2d.drawLine(x1, y1, x2, y2);
        }
    }

    private void drawDistortedText(Graphics2D g2d, String text) {
        Random random = new Random();
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            // Randomly set the x position and y position for distortion
            int x = 20 + (i * 30) + random.nextInt(10); // Adjust x position
            int y = 50 + random.nextInt(10); // Adjust y position
            g2d.drawString(String.valueOf(c), x, y);
        }
    }

    private String generateRandomText(int length) {
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        StringBuilder captcha = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            captcha.append(chars.charAt(random.nextInt(chars.length())));
        }
        return captcha.toString();
    }

    @Autowired
    private Sample sample;


    @GetMapping("/oauth/getVerificationCode/{phoneNum}")
    public ResponseVo getVerificationCode(@PathVariable String phoneNum) throws Exception {
        UUID uuid = UUID.randomUUID();
        String string = uuid.toString().replaceAll("-", "");
        Random random = new Random();
        String i = random.nextInt(900000) + 100000 + "";

        SendSmsResponse sendSmsResponse = sample.sendSms(phoneNum, "{\"code\":" + "\"" + i + "\"}");
        if ("OK".equals(sendSmsResponse.body.code)) {
            userMapper.insertVerifIcationCode(string, i, new Date());
            return ResponseVo.success(string);
        } else
            return ResponseVo.no(sendSmsResponse.body.message);
    }

    @GetMapping("/oauth/LoginWithPhoneNumber/{rid}/{Vcode}/{phoneNum}")
    public ResponseVo LoginWithPhoneNumber(@PathVariable String rid, @PathVariable String Vcode, @PathVariable String phoneNum) throws Exception {
        Map<String, Object> yzm = userMapper.selectVerifIcationCode(rid);
        if (yzm == null)
            return ResponseVo.no("未查询到验证码信息");
        else if (!yzm.get("random_num").equals(Vcode))
            return ResponseVo.success("验证码错误");
        else if (new Date().getTime() - ((Date) yzm.get("inserttime")).getTime() >= 5 * 60 * 1000) {
//            userMapper.deleteYzm(rid);
            return ResponseVo.success("验证码过期,请重新更换验证码");
        }
        LambdaQueryWrapper<LoginUser> eq = new QueryWrapper<LoginUser>().lambda().eq(LoginUser::getPhoneNum, phoneNum);
        LoginUser loginUser = userMapper.selectOne(eq);
        // 清楚已存在token 重制token时长
        deletToken(loginUser.getLoginCode());

        UsernamePasswordAuthenticationToken client = new UsernamePasswordAuthenticationToken("client", null, new ArrayList<>());
        HashMap<String, String> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("grant_type", "password");
        objectObjectHashMap.put("client_id", "client");
        objectObjectHashMap.put("client_secret", "123456");
        objectObjectHashMap.put("username", loginUser.getLoginCode());
        objectObjectHashMap.put("password", loginUser.getPassword());
        ResponseEntity<OAuth2AccessToken> oAuth2AccessTokenResponseEntity = tokenEndpoint.postAccessToken(client, objectObjectHashMap);
// 删除验证码
        userMapper.deleteYzm(rid);
        return ResponseVo.success(oAuth2AccessTokenResponseEntity.getBody());
    }

}
